home *** CD-ROM | disk | FTP | other *** search
-
- // g3dpobj.cpp
- //
- // Copyright (c) 1996 by Toshiaki Tsuji, all rights reserved.
-
- #include "stdgfx.h"
- #include "g3dpobj.h"
- #include "g3dlight.h"
-
- GEOMETRYDATA::GEOMETRYDATA ()
- {
- NumPoints = 0;
- NumPolys = 0;
- SharedCounts = NULL;
- PointVisible = NULL;
- FLPLocalPoints = NULL;
- FLPWorldPoints = NULL;
- FLPCameraPoints = NULL;
- FLPScreenPoints = NULL;
- FLPPointLocalNormals = NULL;
- FLPPointWorldNormals = NULL;
- PointIntensities = NULL;
- HazeValues = NULL;
- InverseZ = NULL;
- Polys = NULL;
- FLPPolyLocalPoints = NULL;
- FLPPolyWorldPoints = NULL;
- FLPPolyLocalNormals = NULL;
- FLPPolyWorldNormals = NULL;
- } // End of Constructor for GEOMETRYDATA
-
- GEOMETRYDATA::~GEOMETRYDATA ()
- {
- DestroyPoints ();
- DestroyPolys ();
- } // End of Destructor for GEOMETRYDATA
-
- BOOLEAN GEOMETRYDATA::CreatePoints ( LONG NewNumPoints )
- {
- DestroyPoints ();
- NumPoints = NewNumPoints;
- SharedCounts = new LONG [NumPoints];
- PointVisible = new BYTE [NumPoints];
-
- FLPLocalPoints = new FLPVECTOR3D [NumPoints];
- FLPWorldPoints = new FLPVECTOR3D [NumPoints];
- FLPCameraPoints = new FLPVECTOR3D [NumPoints];
- FLPScreenPoints = new FLPVECTOR2D [NumPoints];
-
- FLPPointLocalNormals = new FLPVECTOR3D [NumPoints];
- FLPPointWorldNormals = new FLPVECTOR3D [NumPoints];
- PointIntensities = new float [NumPoints];
- HazeValues = new float [NumPoints];
- InverseZ = new float [NumPoints];
- return SUCCESS;
- } // End of CreatePoints for GEOMETRYDATA
-
- BOOLEAN GEOMETRYDATA::CreatePolys ( LONG NewNumPolys )
- {
- DestroyPolys ();
- NumPolys = NewNumPolys;
- Polys = (G3DPOLY*)malloc(sizeof(G3DPOLY)*NumPolys);
- LONG i;
- for (i=0;i<NumPolys;i++)
- {
- Polys[i] = G3DPOLY ();
- Polys[i].ParentObject = NULL;
- } // End for
-
- FLPPolyLocalPoints = new FLPVECTOR3D* [NumPolys];
- FLPPolyWorldPoints = new FLPVECTOR3D* [NumPolys];
- FLPPolyLocalNormals = new FLPVECTOR3D [NumPolys];
- FLPPolyWorldNormals = new FLPVECTOR3D [NumPolys];
- return SUCCESS;
- } // End of CreatePolys for GEOMETRYDATA
-
- VOID GEOMETRYDATA::DestroyPoints ()
- {
- if (FLPLocalPoints!=NULL)
- delete FLPLocalPoints;
- FLPLocalPoints = NULL;
-
- if (FLPWorldPoints!=NULL)
- delete FLPWorldPoints;
- FLPWorldPoints = NULL;
-
- if (FLPCameraPoints!=NULL)
- delete FLPCameraPoints;
- FLPCameraPoints = NULL;
-
- if (FLPScreenPoints!=NULL)
- delete FLPScreenPoints;
- FLPScreenPoints = NULL;
-
- if (FLPPointLocalNormals!=NULL)
- delete FLPPointLocalNormals;
- FLPPointLocalNormals = NULL;
-
- if (FLPPointWorldNormals!=NULL)
- delete FLPPointWorldNormals;
- FLPPointWorldNormals = NULL;
-
- if (PointIntensities!=NULL)
- delete PointIntensities;
- PointIntensities = NULL;
-
- if (HazeValues!=NULL)
- delete HazeValues;
- HazeValues = NULL;
-
- if (InverseZ!=NULL)
- delete InverseZ;
- InverseZ = NULL;
-
- if (SharedCounts!=NULL)
- delete SharedCounts;
- SharedCounts = NULL;
-
- if (PointVisible!=NULL)
- delete PointVisible;
- PointVisible = NULL;
-
- NumPoints = 0;
- } // End of DestroyPoints for GEOMETRYDATA
-
- VOID GEOMETRYDATA::DestroyPolys ()
- {
- if (Polys!=NULL)
- free ( Polys );
- Polys = NULL;
-
- if (FLPPolyLocalPoints!=NULL)
- delete FLPPolyLocalPoints;
- FLPPolyLocalPoints = NULL;
-
- if (FLPPolyWorldPoints!=NULL)
- delete FLPPolyWorldPoints;
- FLPPolyWorldPoints = NULL;
-
- if (FLPPolyLocalNormals!=NULL)
- delete FLPPolyLocalNormals;
- FLPPolyLocalNormals = NULL;
-
- if (FLPPolyWorldNormals!=NULL)
- delete FLPPolyWorldNormals;
- FLPPolyWorldNormals = NULL;
-
- NumPolys = 0;
- } // End of DestroyPolys for GEOMETRYDATA
-
-
- //********************************************************
- //
- // G3D Polygon
- //
- //********************************************************
-
- G3DPOLYHEDRON::G3DPOLYHEDRON () : G3DOBJECT ()
- {
- Type = OBJECT_TYPE_POLYHEDRON;
- InitGeometryData ();
- CurDetail = MAX_DETAIL;
- ClockWised = FALSE;
- DetailData[MAX_DETAIL].FaceFlags = FACE_TEXTURE;
- DetailData[MAX_DETAIL].ShadeFlags = SHADE_GOURAUD;
- DetailData[MED_DETAIL].FaceFlags = FACE_SOLID;
- DetailData[MED_DETAIL].ShadeFlags = SHADE_FLAT;
- DetailData[MIN_DETAIL].FaceFlags = FACE_WIREFRAME;
- DetailData[MIN_DETAIL].ShadeFlags = SHADE_NONE;
- MorphData = NULL;
- TextureMapped = FALSE;
- } // End of Constructor for G3DPOLYHEDRON
-
- G3DPOLYHEDRON::~G3DPOLYHEDRON ()
- {
- DestroyGeometryData ();
- DestroyMorphData ();
- } // End of Destructor for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::SetMaterial ( G3DMATERIAL* Material )
-
- {
- LONG i;
- for (i=0;i<GeometryData.NumPolys;i++)
- {
- GeometryData.Polys[i].Material = Material;
- } // End for
- } // End of SetMaterial for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::InitGeometryData ()
- {
- GeometryData = GEOMETRYDATA ();
- } // End of InitDetailData for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::CreateGeometryData ( LONG NumPoints, LONG NumPolys )
- {
- CreateGeometryPoints ( NumPoints );
- CreateGeometryPolys ( NumPolys );
- } // End of CreateDetailData for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::CreateGeometryPoints ( LONG NumPoints )
- {
- GeometryData.CreatePoints ( NumPoints );
- } // End of CreateGeometryPoints for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::CreateGeometryPolys ( LONG NumPolys )
- {
- GeometryData.CreatePolys ( NumPolys );
- LONG i;
- for (i=0;i<GeometryData.NumPolys;i++)
- {
- GeometryData.Polys[i].ParentObject = this;
- } // End for
- } // End of CreateGeometryPolys for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::DestroyGeometryPoints ()
- {
- GeometryData.DestroyPoints();
- } // End of DestroyGeometryPoints for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::DestroyGeometryPolys ()
- {
- GeometryData.DestroyPolys();
- } // End of DestoryGeometryPoints for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::DestroyGeometryData ()
- {
- DestroyGeometryPoints ();
- DestroyGeometryPolys ();
- } // End of DestroyDetailData for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::SetDetailData ( float Distance )
- {
- LONG i;
- CurDetail = -1;
- for (i=MAX_DETAIL;i>=MIN_DETAIL;i--)
- {
- if (Distance<=DetailData[i].MaxDistance)
- {
- CurDetail = i;
- } // End for
- } // End for
- } // End of SetDetailData for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::SetFaceFlags ( LONG Level, LONG Flags )
- {
- DetailData[Level].FaceFlags = Flags;
- } // End of SetFaceFlags for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::SetShadeFlags ( LONG Level, LONG Flags )
- {
- DetailData[Level].ShadeFlags = Flags;
- } // End of SetShadeFlags for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::UpdateLocalToWorld ()
- {
- G3DOBJECT::UpdateLocalToWorld ();
-
- LONG i;
- LONG NumPoints = GeometryData.NumPoints;
- LONG NumPolys = GeometryData.NumPolys;
- FLPVECTOR3D *LocalPoints;
- FLPVECTOR3D *WorldPoints;
- FLPVECTOR3D *LocalNormals;
- FLPVECTOR3D *WorldNormals;
-
- LocalPoints = GeometryData.FLPLocalPoints;
- WorldPoints = GeometryData.FLPWorldPoints;
-
- LocalNormals = GeometryData.FLPPointLocalNormals;
- WorldNormals = GeometryData.FLPPointWorldNormals;
-
- float x,y,z;
- float nx,ny,nz;
-
- float M00,M01,M02;
- float M10,M11,M12;
- float M20,M21,M22;
- float M30,M31,M32;
- float *MatrixPtr;
-
- MatrixPtr = &(ResultMatrix[0][0]);
-
- M00 = (*MatrixPtr++);
- M01 = (*MatrixPtr++);
- M02 = (*MatrixPtr++);
- MatrixPtr++;
-
- M10 = (*MatrixPtr++);
- M11 = (*MatrixPtr++);
- M12 = (*MatrixPtr++);
- MatrixPtr++;
-
- M20 = (*MatrixPtr++);
- M21 = (*MatrixPtr++);
- M22 = (*MatrixPtr++);
- MatrixPtr++;
-
- M30 = (*MatrixPtr++);
- M31 = (*MatrixPtr++);
- M32 = (*MatrixPtr);
-
- BOOLEAN IsGouraud;
-
- if ((DetailData[CurDetail].ShadeFlags==SHADE_GOURAUD)&&(LightSource!=NULL))
- IsGouraud = TRUE;
- else
- IsGouraud = FALSE;
-
- for (i=0;i<NumPoints;i++)
- {
- x = LocalPoints->x;
- y = LocalPoints->y;
- z = LocalPoints->z;
-
- WorldPoints->x = x*M00+y*M10+z*M20+M30;
- WorldPoints->y = x*M01+y*M11+z*M21+M31;
- WorldPoints->z = x*M02+y*M12+z*M22+M32;
-
- if (IsGouraud)
- {
- nx = LocalNormals->x;
- ny = LocalNormals->y;
- nz = LocalNormals->z;
-
- WorldNormals->x = nx*M00+ny*M10+nz*M20+M30 - WorldPoints->x;
- WorldNormals->y = nx*M01+ny*M11+nz*M21+M31 - WorldPoints->y;
- WorldNormals->z = nx*M02+ny*M12+nz*M22+M32 - WorldPoints->z;
-
- LocalNormals++;
- WorldNormals++;
- } // End if
-
- LocalPoints++;
- WorldPoints++;
- } // End for
-
- LocalNormals = GeometryData.FLPPolyLocalNormals;
- WorldNormals = GeometryData.FLPPolyWorldNormals;
-
- FLPVECTOR3D **PolyWorldPoints;
- G3DPOLY *Polys;
- float x0,y0,z0;
- float x1,y1,z1;
- float x2,y2,z2;
- LONG Point1,Point2;
-
- PolyWorldPoints = GeometryData.FLPPolyWorldPoints;
- Polys = GeometryData.Polys;
-
- for (i=0;i<NumPolys;i++)
- {
- nx = LocalNormals->x;
- ny = LocalNormals->y;
- nz = LocalNormals->z;
-
- x = nx*M00+ny*M10+nz*M20+M30;
- y = nx*M01+ny*M11+nz*M21+M31;
- z = nx*M02+ny*M12+nz*M22+M32;
-
- x0 = (*PolyWorldPoints)->x;
- y0 = (*PolyWorldPoints)->y;
- z0 = (*PolyWorldPoints)->z;
-
- WorldNormals->x = x - x0;
- WorldNormals->y = y - y0;
- WorldNormals->z = z - z0;
-
- LocalNormals++;
- WorldNormals++;
- PolyWorldPoints++;
-
- Point1 = Polys->Points[1];
- Point2 = Polys->Points[2];
-
- x1 = GeometryData.FLPWorldPoints[Point1].x;
- y1 = GeometryData.FLPWorldPoints[Point1].y;
- z1 = GeometryData.FLPWorldPoints[Point1].z;
-
- x2 = GeometryData.FLPWorldPoints[Point2].x;
- y2 = GeometryData.FLPWorldPoints[Point2].y;
- z2 = GeometryData.FLPWorldPoints[Point2].z;
-
- Polys->WorldMinX = MinValue ( x0, MinValue ( x1, x2 ) );
- Polys->WorldMinY = MinValue ( y0, MinValue ( y1, y2 ) );
- Polys->WorldMinZ = MinValue ( z0, MinValue ( z1, z2 ) );
- Polys->WorldMaxX = MaxValue ( x0, MaxValue ( x1, x2 ) );
- Polys->WorldMaxY = MaxValue ( y0, MaxValue ( y1, y2 ) );
- Polys->WorldMaxZ = MaxValue ( z0, MaxValue ( z1, z2 ) );
-
- Polys++;
- } // End for
- } // End of UpdateLocalToWorld for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::UpdateWorldToCamera ( G3DMATRIX CameraMatrix,
- CAMERADATA *CameraData )
- {
- LONG i;
- LONG NumPoints = GeometryData.NumPoints;
- FLPVECTOR3D *WorldPoints;
- FLPVECTOR3D *CameraPoints;
- FLPVECTOR3D *PointWorldNormals;
- FLPVECTOR2D *ScreenPoints;
- float *Intensities;
- float *HazeValues;
- float *InverseZPtr;
-
- G3DOBJECT::UpdateWorldToCamera ( CameraMatrix, CameraData );
-
- if (IsObjectVisible()==FALSE)
- return;
-
- WorldPoints = GeometryData.FLPWorldPoints;
- PointWorldNormals = GeometryData.FLPPointWorldNormals;
- CameraPoints = GeometryData.FLPCameraPoints;
- ScreenPoints = GeometryData.FLPScreenPoints;
- Intensities = GeometryData.PointIntensities;
- HazeValues = GeometryData.HazeValues;
- InverseZPtr = GeometryData.InverseZ;
-
- float M00,M01,M02;
- float M10,M11,M12;
- float M20,M21,M22;
- float M30,M31,M32;
- float *MatrixPtr;
-
- MatrixPtr = &(CameraMatrix[0][0]);
-
- M00 = (*MatrixPtr++);
- M01 = (*MatrixPtr++);
- M02 = (*MatrixPtr++);
- MatrixPtr++;
-
- M10 = (*MatrixPtr++);
- M11 = (*MatrixPtr++);
- M12 = (*MatrixPtr++);
- MatrixPtr++;
-
- M20 = (*MatrixPtr++);
- M21 = (*MatrixPtr++);
- M22 = (*MatrixPtr++);
- MatrixPtr++;
-
- M30 = (*MatrixPtr++);
- M31 = (*MatrixPtr++);
- M32 = (*MatrixPtr);
-
- // Initialize all the points are invisible
- BYTE *PointVisible;
- PointVisible = GeometryData.PointVisible;
- memset ( PointVisible, 0, NumPoints );
-
- CheckMeshVisibility ( CameraData );
-
- LONG ShadeFlags;
- ShadeFlags = MinValue ( DetailData[CurDetail].ShadeFlags, CameraData->ShadeFlags );
-
- float x,y,z;
- float cx,cy,cz;
- float CenterX = CameraData->CenterX;
- float CenterY = CameraData->CenterY;
- float ViewDistance = CameraData->ViewDistance;
- BOOLEAN IsGouraud;
- BOOLEAN DepthCueing;
- float DepthScale;
- BOOLEAN DoHaze;
- float HazeScale;
- float HazeLevels;
-
- DepthCueing = CameraData->DepthCueing;
- DepthScale = CameraData->DepthScale;
-
- DoHaze = CameraData->DoHaze;
- HazeLevels = (float)(CameraData->HazeLevels-1);
- HazeScale = CameraData->HazeScale;
-
- if ((ShadeFlags==SHADE_GOURAUD)&&(LightSource!=NULL))
- {
- IsGouraud = TRUE;
- } // End if
- else
- IsGouraud = FALSE;
-
- for (i=0;i<NumPoints;i++)
- {
- if (*PointVisible)
- {
- x = WorldPoints->x;
- y = WorldPoints->y;
- z = WorldPoints->z;
-
- if (IsGouraud)
- *Intensities = LightSource->ComputeIntensity ( WorldPoints, PointWorldNormals );
-
- cx = x*M00+y*M10+z*M20+M30;
- cy = x*M01+y*M11+z*M21+M31;
- cz = x*M02+y*M12+z*M22+M32;
-
- if (cz==0)
- cz = (float)0.1;
-
- float Ratio;
- *InverseZPtr = Ratio = (float)1/cz;
- if (DepthCueing)
- {
- if (cz>DepthScale)
- (*Intensities) *= Ratio*DepthScale;
- } // End if
-
- if (DoHaze)
- {
- if (cz>HazeScale)
- (*HazeValues) = Ratio*65536*HazeScale*HazeLevels;
- else
- (*HazeValues) = HazeLevels*65536;
- } // End if
-
- ScreenPoints->x = ViewDistance*Ratio*cx + CenterX;
- ScreenPoints->y = -ViewDistance*Ratio*cy + CenterY;
-
- CameraPoints->x = cx;
- CameraPoints->y = cy;
- CameraPoints->z = cz;
- } // End if
-
- PointVisible++;
- WorldPoints++;
- CameraPoints++;
- ScreenPoints++;
- PointWorldNormals++;
- Intensities++;
- HazeValues++;
- InverseZPtr++;
- } // End for
-
- GetPolyMinMax ();
- } // End of UpdateWorldToCamera for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::CheckMeshVisibility ( CAMERADATA *CameraData )
- {
- LONG i,NumPolys;
- G3DPOLY *PolyPtr;
- FLPVECTOR3D *PointList,*Point;
- FLPVECTOR3D CameraPoint = CameraData->CameraPoint;
- LONG NumVisibleShapes = CameraData->NumVisibleShapes;
- G3DSHAPE **VisibleShapes = CameraData->VisibleShapes;
-
- PolyPtr = GeometryData.Polys;
- NumPolys = GeometryData.NumPolys;
- PointList = GeometryData.FLPWorldPoints;
-
- FLPVECTOR3D DirV;
- FLPVECTOR3D *Normals;
- float DotProduct;
- BYTE *PointVisible;
- BOOLEAN IsFlat;
-
- LONG ShadeFlags;
- ShadeFlags = MinValue ( DetailData[CurDetail].ShadeFlags, CameraData->ShadeFlags );
-
- if ((ShadeFlags==SHADE_FLAT)&&(LightSource!=NULL))
- IsFlat = TRUE;
- else
- IsFlat = FALSE;
-
- PointVisible = GeometryData.PointVisible;
- Normals = GeometryData.FLPPolyWorldNormals;
-
- LONG List0,List1,List2;
-
- for (i=0;i<NumPolys;i++)
- {
- List0 = PolyPtr->Points[0];
- Point = &(PointList[List0]);
- FLPVectorSub ( &CameraPoint, Point, &DirV );
- DotProduct = FLPVectorDot ( Normals, &DirV );
- if (DotProduct<=0)
- PolyPtr->Visible = FALSE;
- else
- {
- PolyPtr->Visible = TRUE;
- VisibleShapes[NumVisibleShapes] = PolyPtr;
- NumVisibleShapes++;
- List1 = PolyPtr->Points[1];
- List2 = PolyPtr->Points[2];
- PointVisible[List0] = 1;
- PointVisible[List1] = 1;
- PointVisible[List2] = 1;
-
- if (IsFlat)
- {
- PolyPtr->Intensity =
- LightSource->ComputeIntensity ( Point, Normals );
- } // End if
- } // End else
- Normals++;
- PolyPtr++;
- } // End for
- CameraData->NumVisibleShapes = NumVisibleShapes;
- } // End of CheckMeshVisiblity for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::CountPointShare ()
- {
- LONG i;
- LONG List0,List1,List2;
-
- // Initialize as 0
- for (i=0;i<GeometryData.NumPoints;i++)
- {
- GeometryData.SharedCounts[i] = 0;
- GeometryData.FLPPointLocalNormals[i].x = (float)0;
- GeometryData.FLPPointLocalNormals[i].y = (float)0;
- GeometryData.FLPPointLocalNormals[i].z = (float)0;
- } // End for
-
- // Count
- for (i=0;i<GeometryData.NumPolys;i++)
- {
- List0 = GeometryData.Polys[i].Points[0];
- List1 = GeometryData.Polys[i].Points[1];
- List2 = GeometryData.Polys[i].Points[2];
- GeometryData.SharedCounts[List0]++;
- GeometryData.SharedCounts[List1]++;
- GeometryData.SharedCounts[List2]++;
- GeometryData.FLPPolyLocalPoints[i] = &(GeometryData.FLPLocalPoints[List0]);
- GeometryData.FLPPolyWorldPoints[i] = &(GeometryData.FLPWorldPoints[List0]);
- } // End for
- } // End of CountPointShare for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::ComputePolyLocalNormals ()
- {
- LONG i;
- FLPVECTOR3D V1,V2,Normal;
- FLPVECTOR3D *PointLocalNormals;
-
- PointLocalNormals = GeometryData.FLPPointLocalNormals;
-
- LONG List0,List1,List2;
-
- for (i=0;i<GeometryData.NumPolys;i++)
- {
- List0 = GeometryData.Polys[i].Points[0];
- List1 = GeometryData.Polys[i].Points[1];
- List2 = GeometryData.Polys[i].Points[2];
-
- FLPVectorSub ( &(GeometryData.FLPLocalPoints[List0]),
- &(GeometryData.FLPLocalPoints[List1]),
- &V1 );
- FLPVectorSub ( &(GeometryData.FLPLocalPoints[List0]),
- &(GeometryData.FLPLocalPoints[List2]),
- &V2 );
- FLPVectorCross ( &V1, &V2, &Normal );
- FLPVectorNormalize ( &Normal );
-
- if (ClockWised) // If clock-wise, then flip normal
- {
- Normal.x = -Normal.x;
- Normal.y = -Normal.y;
- Normal.z = -Normal.z;
- } // End if
-
- PointLocalNormals[List0].x += Normal.x;
- PointLocalNormals[List0].y += Normal.y;
- PointLocalNormals[List0].z += Normal.z;
-
- PointLocalNormals[List1].x += Normal.x;
- PointLocalNormals[List1].y += Normal.y;
- PointLocalNormals[List1].z += Normal.z;
-
- PointLocalNormals[List2].x += Normal.x;
- PointLocalNormals[List2].y += Normal.y;
- PointLocalNormals[List2].z += Normal.z;
-
- FLPVectorAdd ( &Normal, &(GeometryData.FLPLocalPoints[List0]),
- &(GeometryData.FLPPolyLocalNormals[i]) );
- } // End for
- } // End of ComputePolyLocalNormals for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::ComputePointLocalNormals ()
- {
- LONG i;
- FLPVECTOR3D *LocalPoints;
- FLPVECTOR3D *Normals;
-
- LocalPoints = GeometryData.FLPLocalPoints;
- Normals = GeometryData.FLPPointLocalNormals;
-
- for (i=0;i<GeometryData.NumPoints;i++)
- {
- float Ratio;
- if (GeometryData.SharedCounts[i]>0)
- {
- Ratio = (float)1/(float)GeometryData.SharedCounts[i];
- Normals[i].x *= Ratio;
- Normals[i].y *= Ratio;
- Normals[i].z *= Ratio;
- } // End if
-
- FLPVectorNormalize ( &(Normals[i]) );
- Normals[i].x += LocalPoints[i].x;
- Normals[i].y += LocalPoints[i].y;
- Normals[i].z += LocalPoints[i].z;
- } // End for
- } // End of ComputePointLocalNormals for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::GetPolyMinMax ()
- {
- G3DPOLY *PolyPtr;
- FLPVECTOR3D *CameraPoints;
-
- PolyPtr = GeometryData.Polys;
- CameraPoints = GeometryData.FLPCameraPoints;
-
- LONG i;
- LONG List0,List1,List2;
- float z0,z1,z2;
-
- for (i=0;i<GeometryData.NumPolys;i++)
- {
- if (PolyPtr->Visible)
- {
- List0 = PolyPtr->Points[0];
- List1 = PolyPtr->Points[1];
- List2 = PolyPtr->Points[2];
- z0 = CameraPoints[List0].z;
- z1 = CameraPoints[List1].z;
- z2 = CameraPoints[List2].z;
-
- PolyPtr->MinZ = MinValue ( z0, MinValue ( z1, z2 ) );
- PolyPtr->MaxZ = MaxValue ( z0, MaxValue ( z1, z2 ) );
- } // End if
- PolyPtr++;
- } // End for
- } // End of GetPolyMinMax for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::MapTexture ( float U0, float V0,
- float U1, float V1,
- float U2, float V2 )
- {
- double IntPart;
- if (U0>(float)1.0)
- U0 = modf ( (double)U0, &IntPart );
- if (V0>(float)1.0)
- V0 = modf ( (double)V0, &IntPart );
- if (U1>(float)1.0)
- U1 = modf ( (double)U1, &IntPart );
- if (V1>(float)1.0)
- V1 = modf ( (double)V1, &IntPart );
- if (U2>(float)1.0)
- U2 = modf ( (double)U2, &IntPart );
- if (V2>(float)1.0)
- V2 = modf ( (double)V2, &IntPart );
-
- LONG i;
- for (i=0;i<GeometryData.NumPolys;i++)
- {
- GeometryData.Polys[i].TexCoords[0].x = U0*255*65536;
- GeometryData.Polys[i].TexCoords[0].y = V0*255*65536;
- GeometryData.Polys[i].TexCoords[1].x = U1*255*65536;
- GeometryData.Polys[i].TexCoords[1].y = V1*255*65536;
- GeometryData.Polys[i].TexCoords[2].x = U2*255*65536;
- GeometryData.Polys[i].TexCoords[2].y = V2*255*65536;
- } // End for
- } // End of MapTexture for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::Init ()
- {
- ComputeCenter ();
-
- LISTOBJECT<G3DOBJECT*> *ObjectNode;
- ObjectNode = SubObjectList->GetHead ();
-
- while (ObjectNode!=NULL)
- {
- ObjectNode->Data->Init ();
- ObjectNode = ObjectNode->NextObject;
- } // End while
-
- CountPointShare ();
- ComputePolyLocalNormals ();
- ComputePointLocalNormals ();
- } // End of Init for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::CountShapes ( LONG *Count )
- {
- *Count += GeometryData.NumPolys;
- } // End of CountShapes for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::ComputeCenter ()
- {
- LONG i;
- float MinX,MaxX;
- float MinY,MaxY;
- float MinZ,MaxZ;
-
- if (GeometryData.FLPLocalPoints==NULL)
- {
- return;
- } // End if
-
- MinX = MaxX = GeometryData.FLPLocalPoints[0].x;
- MinY = MaxY = GeometryData.FLPLocalPoints[0].y;
- MinZ = MaxZ = GeometryData.FLPLocalPoints[0].z;
-
- for (i=1;i<GeometryData.NumPoints;i++)
- {
- if (GeometryData.FLPLocalPoints[i].x<MinX)
- MinX = GeometryData.FLPLocalPoints[i].x;
- else if (GeometryData.FLPLocalPoints[i].x>MaxX)
- MaxX = GeometryData.FLPLocalPoints[i].x;
-
- if (GeometryData.FLPLocalPoints[i].y<MinY)
- MinY = GeometryData.FLPLocalPoints[i].y;
- else if (GeometryData.FLPLocalPoints[i].y>MaxY)
- MaxY = GeometryData.FLPLocalPoints[i].y;
-
- if (GeometryData.FLPLocalPoints[i].y<MinZ)
- MinZ = GeometryData.FLPLocalPoints[i].z;
- else if (GeometryData.FLPLocalPoints[i].z>MaxZ)
- MaxZ = GeometryData.FLPLocalPoints[i].z;
- } // End for
-
- FLPLocalCenter.x = ( MaxX + MinX ) / 2;
- FLPLocalCenter.y = ( MaxY + MinY ) / 2;
- FLPLocalCenter.z = ( MaxZ + MinZ ) / 2;
- } // End of ComputeCenter for G3DPOLYHEDRON
-
- float G3DPOLYHEDRON::ComputeRadius ()
- {
- float Distance;
- float MaxDist;
-
- LONG i;
-
- MaxDist = (float)0;
- FLPVECTOR3D Center;
- FLPVECTOR3D Point;
-
- Center = FLPLocalCenter;
-
- for (i=0;i<GeometryData.NumPoints;i++)
- {
- Point = GeometryData.FLPLocalPoints[i];
- Distance = FLPVectorDistance ( &Center,
- &Point );
- if (MaxDist<Distance)
- MaxDist = Distance;
- } // End for
-
- LISTOBJECT<G3DOBJECT*> *ObjectNode;
- FLPVECTOR3D SubCenter;
- G3DOBJECT *Object;
- ObjectNode = SubObjectList->GetHead ();
-
- while (ObjectNode!=NULL)
- {
- Object = ObjectNode->Data;
- SubCenter = Object->GetLocalCenter ();
- Distance = Object->ComputeRadius ();
- Distance += FLPVectorDistance ( &FLPLocalCenter, &SubCenter );
- if (MaxDist<Distance)
- MaxDist = Distance;
- ObjectNode = ObjectNode->NextObject;
- } // End while
-
- Radius = MaxDist;
- return MaxDist;
- } // End of ComputeRadius for G3DPOLYHEDRON
-
- float G3DPOLYHEDRON::ComputeTforPoly ( FLPVECTOR3D Normal, FLPVECTOR3D Base, FLPVECTOR3D Dir )
- {
- float T;
- float Denom,Value;
-
- Denom = Normal.x*Dir.x+Normal.y*Dir.y+Normal.z*Dir.z;
- Value = Normal.x*Base.x+Normal.y*Base.y+Normal.z*Base.z+Normal.w;
- if (Denom==0)
- return (float)(-1);
-
- T = (-Value)/Denom;
-
- return T;
- } // End of ComputeTforPoly for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::CheckCollision ( FLPVECTOR3D StartPt, FLPVECTOR3D EndPt,
- COLLIDEDATA* CollideList, LONG *CurNum, LONG MaxNum,
- float CollideDist, float Gap )
- {
- if (*CurNum>=MaxNum)
- return;
-
- float MinX,MinY,MinZ;
- float MaxX,MaxY,MaxZ;
-
- MinX = FLPWorldCenter.x - Radius;
- MaxX = FLPWorldCenter.x + Radius;
- MinY = FLPWorldCenter.y - Radius;
- MaxY = FLPWorldCenter.y + Radius;
- MinZ = FLPWorldCenter.z - Radius;
- MaxZ = FLPWorldCenter.z + Radius;
-
- if (((StartPt.x>MinX)&&(StartPt.x<MaxX)&&
- (StartPt.y>MinY)&&(StartPt.y<MaxY)&&
- (StartPt.z>MinZ)&&(StartPt.z<MaxZ)) ||
- ((EndPt.x>MinX)&&(EndPt.x<MaxX)&&
- (EndPt.y>MinY)&&(EndPt.y<MaxY)&&
- (EndPt.z>MinZ)&&(EndPt.z<MaxZ)))
- {
- FLPVECTOR3D Dir,Normal;
- G3DPOLY *Polys;
- FLPVECTOR3D *NormalPtr;
- FLPVECTOR3D **PolyPointPtr;
- float wx,wy,wz;
-
- FLPVectorSub ( &StartPt, &EndPt, &Dir );
- Polys = GeometryData.Polys;
- PolyPointPtr = GeometryData.FLPPolyWorldPoints;
- NormalPtr = GeometryData.FLPPolyWorldNormals;
- LONG i;
- for (i=0;i<GeometryData.NumPolys;i++)
- {
- wx = (*PolyPointPtr)->x;
- wy = (*PolyPointPtr)->y;
- wz = (*PolyPointPtr)->z;
- Normal.x = NormalPtr->x;
- Normal.y = NormalPtr->y;
- Normal.z = NormalPtr->z;
- Normal.w = -(Normal.x*wx+Normal.y*wy+Normal.z*wz);
- float T;
- FLPVECTOR3D I; // Intersection Point
-
- T = ComputeTforPoly ( Normal, StartPt, Dir );
- if ((T>0)&&(T<CollideDist))
- {
- I.x = StartPt.x + T*Dir.x;
- I.y = StartPt.y + T*Dir.y;
- I.z = StartPt.z + T*Dir.z;
- if ((I.x>Polys->WorldMinX-Gap)&&(I.x<Polys->WorldMaxX+Gap)&&
- (I.y>Polys->WorldMinY-Gap)&&(I.y<Polys->WorldMaxY+Gap)&&
- (I.z>Polys->WorldMinZ-Gap)&&(I.z<Polys->WorldMaxZ+Gap))
- {
- CollideList[*CurNum].Shape = Polys;
- CollideList[*CurNum].CollideT = T;
- (*CurNum)++;
- if (*CurNum>=MaxNum)
- return;
- } // End if
- } // End if
- Polys++;
- PolyPointPtr++;
- NormalPtr++;
- } // End for
- LISTOBJECT<G3DOBJECT*> *ObjectNode;
- G3DOBJECT *Object;
- ObjectNode = SubObjectList->GetHead ();
-
- while (ObjectNode!=NULL)
- {
- Object = ObjectNode->Data;
- Object->CheckCollision ( StartPt, EndPt, CollideList, CurNum, MaxNum,
- CollideDist, Gap );
- ObjectNode = ObjectNode->NextObject;
- } // End while
- } // End if
- } // End of CheckCollision for G3DPOLYHEDRON
-
- BOOLEAN G3DPOLYHEDRON::CreateMorphData ( GEOMETRYDATA *TargetGeometry, LONG NumFrames )
- {
- if (NumFrames<=0)
- return FAILURE;
-
- FLPVECTOR3D *NewPoints;
- FLPVECTOR3D *OldPoints;
-
- NewPoints = TargetGeometry->FLPLocalPoints;
- OldPoints = GeometryData.FLPLocalPoints;
-
- DestroyMorphData ();
- MorphData = new MORPHDATA;
- if (MorphData==NULL)
- return FAILURE;
- MorphData->FLPLocalPointsDelta = new FLPVECTOR3D [TargetGeometry->NumPoints];
- if (MorphData->FLPLocalPointsDelta==NULL)
- DestroyMorphData ();
- MorphData->NumFrames = NumFrames;
-
- LONG i;
- float Ratio;
- Ratio = (float)1/NumFrames;
- FLPVECTOR3D *Deltas;
-
- Deltas = MorphData->FLPLocalPointsDelta;
- for (i=0;i<TargetGeometry->NumPoints;i++)
- {
- Deltas->x = (NewPoints->x-OldPoints->x)*Ratio;
- Deltas->y = (NewPoints->x-OldPoints->y)*Ratio;
- Deltas->z = (NewPoints->x-OldPoints->z)*Ratio;
- Deltas++;
- NewPoints++;
- OldPoints++;
- } // End for
- MorphData->CurFrame = 0;
- return 0;
- } // End of CreateMorhData for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::DestroyMorphData ()
- {
- if (MorphData!=NULL)
- {
- if (MorphData->FLPLocalPointsDelta!=NULL)
- delete MorphData->FLPLocalPointsDelta;
- delete MorphData;
- } // End if
- MorphData = NULL;
- } // End of DestroyMorhData for G3DPOLYHEDRON
-
- VOID G3DPOLYHEDRON::Warp ( LONG NumSteps )
- {
- if (MorphData==NULL)
- return;
- if (MorphData->FLPLocalPointsDelta==NULL)
- return;
-
- FLPVECTOR3D *Deltas;
- FLPVECTOR3D *Points;
- LONG i;
-
- Deltas = MorphData->FLPLocalPointsDelta;
- Points = GeometryData.FLPLocalPoints;
-
- if (NumSteps+MorphData->CurFrame>=MorphData->NumFrames)
- NumSteps = MorphData->NumFrames-MorphData->CurFrame-1;
-
- if (NumSteps<=0)
- return;
-
- if (NumSteps==1)
- {
- for (i=0;i<GeometryData.NumPoints;i++)
- {
- Points->x += Deltas->x;
- Points->y += Deltas->y;
- Points->z += Deltas->z;
- Points++;
- Deltas++;
- } // End for
- } // End if
- else
- {
- for (i=0;i<GeometryData.NumPoints;i++)
- {
- Points->x += Deltas->x*NumSteps;
- Points->y += Deltas->y*NumSteps;
- Points->z += Deltas->z*NumSteps;
- Points++;
- Deltas++;
- } // End for
- } // End else
-
- MorphData->CurFrame++;
- if (MorphData->CurFrame>=MorphData->NumFrames-1)
- DestroyMorphData ();
- } // End of Warp for G3DPOLYHEDRON
-
-
-